'''
拿来只传输文件的，模拟网络拥塞场景。
'''
import math
import platform
from pstats import SortKey
from tkinter.tix import Tree
import cv2, imutils, socket
import numpy as np
import time, os
import base64
import threading, wave, pickle, struct, sys

timelist = []
allspeedlist = [] # 仅做测试显示 带宽总变化情况
speedlist = []

is_slice = 0

aimIp = "10.21.181.110" # 端口见if-main里面 192.168.1.106 10.21.179.204  10.12.55.166
recv_count = 0.0 # 统计速率
DEBUG = 1
g_th_flag = True
print('等待渲染服务器发送文件:')
print('抢占带宽用的客户端')
BUFF_SIZE = 65536

# 建立socket通信。第三个参数为1时是UDP(和渲染服务器通信)
def socket_bulid(ipaddr, port, isudp):
    try:
        if isudp == 1:
            s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
            s.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
            s.sendto('Start video withoutfps'.encode('utf-8'), (ipaddr, port)) # 往渲染服务器发送消息
            # print('send:', 'Start video withoutfps', (ipaddr, port))
            ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
            ss.bind((aimIp, s.getsockname()[1] + 1))
            ss.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
            return ss
        else:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((ipaddr, port))
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    return s

# 两个list转换的工具类函数
def iListTStr(l):
    lstr = [str(x) for x in l]
    return ', '.join(lstr)
def strListTf(l):
    li = [float(x) for x in l]
    return li

# 按需分类模块：
# 返回整型表示的用户需求
def getreq(resol, fps, gametype):
    if resol == 720 and fps == 30: # 低带宽
        if gametype: # 低时延
            return 2
        else:
            return 0
    elif resol == 1080 and fps == 60:
        if gametype:
            return 3
        else:
            return 1
    return -1

# 网络测量模块：
# 函数1：测量带宽(kbps)
def getspeed():
    global recv_count, speedlist # 存的是float形式
    time.sleep(1) # 先让渲染通信进入正常状态
    while g_th_flag:
        recvcount = 0.0
        time.sleep(1)
        recvcount = recvcount / 1000 * 8 #速率领域的kbps似乎是1000进制！
        speedlist.append(recvcount)
        allspeedlist.append(recvcount)
        if(len(speedlist) > 120):
            speedlist.pop(0)
        print(f'speed:{recvcount} kbps')
        


# 和渲染服务器通信的函数
def video_stream(video_socket): # 接收视频流 UDP
    global recv_count, g_th_flag # 统计带宽
    # cv2.namedWindow('RECEIVING VIDEO')        
    # cv2.moveWindow('RECEIVING VIDEO', 10,360) 
    fps,st,frames_to_count,cnt = (0,0,10,0)
    while g_th_flag:
        packet, _ = video_socket.recvfrom(BUFF_SIZE)
        # viddata = base64.b64decode(packet,' /')
        npdata = np.frombuffer(packet, dtype=np.uint8)
        recv_count += len(npdata)

        frame = cv2.imdecode(npdata,1)

    video_socket.close()
    cv2.destroyAllWindows() 



if __name__ == '__main__':
    # 初始化
    vid_soc = socket_bulid(aimIp, 5051, 1) # 渲染服务器
    # 预先感知文件长度
    # 开启网络质量监测
    t1 = threading.Thread(target = getspeed)
    t1.setDaemon(True) # 能随着control-c一起退出
    t1.start()
    # t2 = threading.Thread(target = getother)
    # t2.setDaemon(True)
    # t2.start()

    # 进入通信
    try:
        t3 = threading.Thread(target = video_stream, args=(vid_soc, ))
        t3.setDaemon(True)
        t3.start()
        t1.join()
        # t2.join()
        t3.join()
    except KeyboardInterrupt as e:
        g_th_flag = False
        print('客户端结束运行')
        os._exit(0)
